var Poker = require('../Poker/Poker');
var PokerRoom = require('../Poker/room').PokerRoom;

var Const = require('./const');
var SubCode = require('../subCode');

var RoundStatus = {
    'WAITING': 1,   // 等待其它玩家准备
    'PREPARE': 2,   // 准备人数足够，将继续等待，其它玩家依然可以准备
    'READY': 3,     // 就绪，开始游戏
    'ROBDEALER' : 4,// 抢庄
    'ADDANTE': 5,   // 加注
    'PLAY': 6       // 玩家选牌
};

exports.HLNNRoom = PokerRoom.extend({
    _roundStatus: RoundStatus.WAITING,

    _dealerIndex: 0,           // 庄家坐位
    _selectWaitTime: 0,        // 开始选牌的时间
    _waitRobTime: 0,           // 开始抢庄的时间
    _waitAddAnteTime: 0,       // 开始加注的时间
    _waitTimer: 0,             // 计时器
    _roundAnte: 0,             // 本轮注数
    _roundWinPlayer: 0,        // 本轮赢家
    _roundDateStamp: 0,        // 当前局数操作的时间戳
    _roundTurn: 0,

    init: function(rid, creator, msg) {
        this._super(rid, creator, msg);

        this._roundStatus = RoundStatus.WAITING;

        // 房主当庄和轮流当庄，默认第一局都是房主当庄
        if (this.getOption("qZhuangMode") == Const.qZhuangMode.FZZ
            || this.getOption("qZhuangMode" == Const.qZhuangMode.LLZZ)) {
            this._dealerIndex = 1;
        } else {
            this._dealerIndex = 0;
        }

        if (! this.getOption("isColorCard")) {
            this.getSubConfig().removeCards = Const.removeCards;
            console.log ("当前需要移除的牌：" + this.getSubConfig().removeCards);
        }

        this._waitTimer = 0;
        this._selectWaitTime = 0;
        this._roundAnte = 0;
        this._roundTurn = 0;
        this._roundDateStamp = 0;
    },

    /**
     * 获取当前步骤的等待时间
     * @returns {*}
     */
    getWaitStepTime : function () {

        var step = this._roundStatus;
        var time;
        switch (step) {
            case RoundStatus.ADDANTE:time = this.getHideOption("addAnteWaitMS");break;
            case RoundStatus.PLAY: time = this.getHideOption("playWaitMS");break;
            case RoundStatus.ROBDEALER:time = this.getHideOption("robDealerWaitMS");break;
        }

        return time;
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getRoundInfo: function() {
        var info = this._super();
        info.robDealerWaitMS = this.getHideOption("robDealerWaitMS");
        info.selectWaitMS = this.getHideOption("selectWaitMS");
        info.dealerIndex = this.getDealerIndex();
        return info;
    },

    getReconnectInfo: function (rePlayer) {
        var info = this._super(rePlayer);
        info.dealer = this._dealerIndex;
        info.selectWaitTime = this._selectWaitTime;
        info.roundAnte = this._roundAnte;
        info.roundTurn = this._roundTurn;
        info.roundStatus = this._roundStatus;

        var waitTime = this.getWaitStepTime();
        if (waitTime) {
            info.waitTime = waitTime;
            info.dateStamp = this._roundDateStamp;
        }

        return info;
    },

    getRoomConfig: function (){
        var cfg = this._super();
        cfg.destroyWaitTime = 120;
        cfg.waitTimeoutTime = 90;
        cfg.resetDestroyOnNewRound = 0;
        return cfg;
    },

    /**
     * 检查是否可开始新的一局
     * @returns {boolean}
     */
    checkStartNewRound: function () {

        if (this.isPlaying()) {
            return false;
        }

        if (this.getReadyPlayerCount() == this.getPlayerCount()
        &&  this.getReadyPlayerCount() >= this.getSubConfig().minPlayer) {

            this._roundStatus = RoundStatus.READY;
            return true;
        }

        return false;
    },

    onPlayerQuitRoom: function(player) {
        this._super(player);

        if (this._roundStatus != RoundStatus.PREPARE) {
            return;
        }

        if (this.getReadyPlayerCount() <= this.getSubConfig().roomPlayerMin) {
            this.broadcast("onCancelStartWait", {});
            this._roundStatus = RoundStatus.WAITING;
        }
    },

    onBeforeStartNewRound: function() {
        this._super();
        this._selectWaitTime = 0;
        this._roundTurn = 0;

        // 如果是轮流坐庄的话, 需要这个时候进行庄家的移动
        if (this.getOption("qZhuangMode") == Const.qZhuangMode.FZZ) {
            this._dealerIndex = 1;
        }else if (this.getOption("qZhuangMode") == Const.qZhuangMode.LLZZ) {
            this._dealerIndex = this.getNextPlayer(this.getDealerIndex());
        }else {
            // 需要抢庄的之前的庄位置重置
            this._dealerIndex = 0;
        }
    },

    onAfterStartNewRound: function() {
        this._super();
        this._startPlay();
    },

    // 主要用于中途解散没有销毁
    onDestroy: function() {
        this._super();
        if(this._waitTimer){
            clearTimeout(this._waitTimer);
        }

        // 清空默认配置
        if (this.getSubConfig().removeCards.length >= 1) {
            this.getSubConfig().removeCards = [];
        }
    },

    onSettlement: function() {
        this._super();
        if(this.getOption("qZhuangMode") == "ZNMS"){
            this.enumPlaying(function(eIndex, ePlayer) {
                if(ePlayer._giveUp){
                    return;
                }
                if(eIndex == this._roundWinPlayer){
                    return;
                }
                if(this._roundWinPlayer){
                    if(ePlayer._compar(this._roundWinPlayer)){
                        this._roundWinPlayer = eIndex;
                    }
                }else{
                    this._roundWinPlayer = eIndex;
                }
                //ePlayer.settlementPattern();
            }.bind(this));
        } else {

            // 首先结算房主的牌型
            // 然后让房主与玩家逐个比较
            var dealerPlayer = this.getDealerPlayer();

            if (!dealerPlayer.getSelectedCards()) {
                dealerPlayer.checkPattern();
            }

            this.enumPlaying(function(eIndex, ePlayer) {

                if (ePlayer && this.getDealerIndex() != eIndex) {

                    if (!dealerPlayer.getSelectedCards()) {
                        ePlayer.checkPattern();
                    }

                    var result = ePlayer.compareEach (dealerPlayer);
                    var resFloat = result ? 1 : -1;
                    var winPlayer = result ? ePlayer : dealerPlayer;

                    var score;
                    if (this.getOption("youNiuFan")) {

                        var value = winPlayer.getRoundPattern() - Const.Pattern.wuNiu;

                        if (winPlayer.getRoundPattern() == Const.Pattern.wuNiu) {
                            value = 1;
                        }else if (winPlayer.getRoundPattern() > Const.Pattern.niuniu) {
                            value = 10;
                        }

                        score = value * ePlayer.getAnte() * resFloat;
                    }else {
                        score = resFloat * ePlayer.getAnte() * winPlayer.getRoundPatternScore();
                    }

                    console.log ("玩家获取积分:" + score + " 当前玩家获胜结果:" + result);
                    ePlayer.addRoundScore (score);
                    dealerPlayer.addRoundScore (-score);
                }
            }.bind (this));
        }
    },

    onCurRoundFinished: function() {
        this._super();
        this._roundStatus = RoundStatus.WAITING;
        this._roundDateStamp = 0;
        this._dealerIndex = 0;

        if(this._waitTimer){
            clearTimeout(this._waitTimer);
        }
    },

    /******************************************************************
     * 功能接口
     ******************************************************************/

    handleRobDealer: function(player, msg, callback) {
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }

        if (this.getOption("qZhuangMode") != Const.qZhuangMode.JDQZ
            && this.getOption("qZhuangMode") != Const.qZhuangMode.FFQZ) {
            callback({code: SubCode.QZNN_MS_UNMATCH}); return;
        }

        if (player.getRobDealer() != -1) {
            callback({code: SubCode.QZNN_ROB_DEALER_SET}); return;
        }

        if (!msg.hasOwnProperty('value') || isNaN(msg.value)) {
            callback({code: Code.ARGS_INVALID}); return;
        }

        var value = parseInt(msg.value);
        if (value != 0 && value != 1) {
            callback({code: Code.ARGS_VALUE_WRONG}); return;
        }

        player.setRotDealer(value);
        this.broadcast("onPlayerRobDealer", {
            playerIndex: player.getIndex(),
            value: value
        });
        callback({});

        var isAllSet = true;
        this.enumPlaying(function(eIndex, ePlayer) {
            if (ePlayer.getRobDealer() == -1) {
                isAllSet = false;
            }
        });

        if (isAllSet) {

            console.log ("所有玩家都已经抢庄完毕: ");

            if (this._waitTimer) {
                clearTimeout(this._waitTimer);
            }

            this._dealRobDealerAllSet();
        }
    },

    handlePlayCards : function (player, msg, callback) {

        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }
        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }
        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }
        if(player._playCards){
            callback({code: SubCode.QZNN_PLAY_CARD_END}); return;
        }

        callback({});

        player._playCards = true;
        player.checkPattern();

        var resp = {
            playerIndex: player.getIndex(),
            handCards: player.getHandCards().getInitCards(),
            selectedCards: player._selectedCards,
            niu: player._stat.roundPattern
        };
        this.broadcast("onPlayCards", resp);

        var isAllPlayed = true;
        this.enumPlaying(function(eIndex, ePlayer) {
            if (ePlayer._playCards == false) {
                isAllPlayed = false;
            }
        });

        if (isAllPlayed) {
            //this.broadcast("onSelectCardsFinish", {});
            this.broadcast("onPlayCardsFinish", {});

            if (this._waitTimer) {
                clearTimeout(this._waitTimer);
            }

            this.settlementCurRound(500);
        }
    },

    //加注
    handleAddAnte : function (player, msg, callback) {
        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }

        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }

        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }

        if (!msg.hasOwnProperty('num') || isNaN(msg.num)) {
            callback({code: Code.ARGS_INVALID}); return;
        }

        if(player.getAnte()){
            callback({code: SubCode.QZNN_ANTE_ADDED}); return;
        }

        //if (this.getOption("freeScore")
        //    && msg.num <= 0 && msg.num > 20) {
        //    callback({code: SubCode.QZNN_ANTE_ADDED}); return;
        //} if (!this.getOption("freeScore")
        //    && msg.num <= 0 && msg.num > 5) {
        //    callback({code: SubCode.QZNN_ANTE_ADDED}); return;
        //}

        var addAnet = msg.num;
        callback({});

        player.setAnte(addAnet);

        this.broadcast("onPlayerAddAnte", {
            playerIndex: player.getIndex(),
            num: addAnet
        });

        var isAllAdded = true;
        var room = this;
        this.enumPlaying(function(eIndex, ePlayer) {
            if (ePlayer.getAnte() == 0 && eIndex != room._dealerIndex) {
                isAllAdded = false;
            }
        });

        if (isAllAdded) {
            this.broadcast("onAddAnteFinish", {});

            if (this._waitTimer) {
                clearTimeout(this._waitTimer);
            }

            this._waitPlayCards();
        }
    },

    //选牌（已废）
    handleSelectCards: function(player, msg, callback) {
        if (!msg.cards) {
            callback({code: Code.ARGS_INVALID}); return;
        }

        if (!player.isPlaying()) {
            callback({code: Code.PLAYER_NOT_PLAYING}); return;
        }

        if (!this.isPlaying()) {
            callback({code: Code.ROOM_NOT_PLAYING}); return;
        }

        if (this.isCurRoundFinished()) {
            callback({code: Code.ROOM_ROUND_FINISHED}); return;
        }

        var cards = msg.cards;
        if (!ExObject.isArray(cards)) {
            callback({code: Code.ARGS_VALUE_WRONG}); return;
        }

        if (!player.setSelectedCards(cards)) {
            callback({code: SubCode.CARD_NOT_EXIST}); return;
        }

        this.broadcast("onPlayerSelectCards", {
            playerIndex: player.getIndex(),
            selectNum: msg.cards.length
        });

        callback({});
        player.checkPattern(cards);

        var isAllSelected = true;
        this.enumPlaying(function(eIndex, ePlayer) {
            if (!ePlayer.isSelectedCards()) {
                isAllSelected = false;
            }
        });

        if (isAllSelected) {
            this.broadcast("onSelectCardsFinish", {});
            this.settlementCurRound(500);
        }
    },

    //_startNewRoundAfter: function(timeMS) {
    //    if (this._roundStatus != RoundStatus.WAITING) {
    //        return;
    //    }
    //
    //    if (timeMS == 0) {
    //        this.broadcast("onRoomStartAfter", {
    //            time: timeMS
    //        });
    //    }
    //
    //    this._roundStatus = RoundStatus.PREPARE;
    //
    //    setTimeout(function() {
    //        if (this._roundStatus != RoundStatus.PREPARE) {
    //            return;
    //        }
    //
    //        this._roundStatus = RoundStatus.READY;
    //        this.tryStartNewRound();
    //    }.bind(this), timeMS);
    //},

    _startPlay: function() {
        this.initPlayersHandCards();

        if (this.getOption("qZhuangMode") == Const.qZhuangMode.FZZ
            || this.getOption("qZhuangMode") == Const.qZhuangMode.LLZZ) {
            this._waitAddAnte();
        }else if(this.getOption("qZhuangMode") == Const.qZhuangMode.FFQZ) {
            this._waitRobDealer();
        }else if (this.getOption("qZhuangMode") == Const.qZhuangMode.JDQZ) {
            this._waitRobDealer();
        }
    },

    /**
     * 重载单独处理发送
     */
    initPlayersHandCards : function () {

        this.enumPlayers(function (eIndex, ePlayer) {

            if (ePlayer) {
                ePlayer.InitHandCards(this._publicCards.getCards(ePlayer.getInitHandCardNeedNum(), ePlayer.getInitHandCardPreCards()));
            }
        }.bind(this));
    },

    _waitRobDealer: function() {
        this._waitRobTime = Date.getStamp();
        this._roundDateStamp = new Date().getTime();

        this.broadcast("onStartRobDealer", {
            waitRobTime: this.getHideOption("robDealerWaitMS"),
            dateStamp: this._roundDateStamp
        });

        this._roundStatus = RoundStatus.ROBDEALER;

        if(this._waitTimer){
            clearTimeout(this._waitTimer);
        }

        this._waitTimer = setTimeout(function() {
            if (!this.isPlaying()) {
                return;
            }

            if (this._roundStatus != RoundStatus.ROBDEALER) {
                return;
            }

            this.enumPlaying(function(eIndex, ePlayer) {
                if (ePlayer.getRobDealer() == -1) {
                    ePlayer.setRotDealer(0);
                    this.broadcast("onPlayerRobDealer", {
                        playerIndex: ePlayer.getIndex(),
                        value: 0
                    });
                }
            }.bind(this));

            this._dealRobDealerAllSet();

        }.bind(this), this.getHideOption("robDealerWaitMS"));
    },

    _dealRobDealerAllSet: function() {
        var arr0 = [];
        var arr1 = [];

        // （用于检查房间里面的玩家）
        this.enumPlayers(function(eIndex, ePlayer) {
            if (ePlayer.getRobDealer()) {
                arr1.push(eIndex);
            } else {
                arr0.push(eIndex);
            }
        });

        var randIndex0 = Ext.randArray(arr0);
        var randIndex1 = Ext.randArray(arr1);
        var length = arr1.length;

        if (randIndex1) {
            this._dealerIndex = randIndex1;
        }else {
            this._dealerIndex = randIndex0;
        }

        this.broadcast("onDealerChanged", {
            dealer: this._dealerIndex,
            length: length
        });
        this._waitAddAnte();
    },

    _waitAddAnte: function(){
        this._roundStatus = RoundStatus.ADDANTE;
        this._waitAddAnteTime = Date.getStamp();
        this._roundDateStamp = new Date().getTime();

        this.broadcast("onStartAddAnte", {
            waitAddAnteTime: this.getHideOption("addAnteWaitMS"),
            dateStamp: this._roundDateStamp
        });

        if(this._waitTimer){
            clearTimeout(this._waitTimer);
        }

        this._waitTimer = setTimeout(function() {
            if (!this.isPlaying()) {
                return;
            }
            if (this._roundStatus != RoundStatus.ADDANTE) {
                return;
            }
            console.log("addAnteWaitMS = %d", this.getHideOption("addAnteWaitMS"));
            this.enumPlaying(function(eIndex, ePlayer) {
                if (ePlayer.getAnte() == 0 && eIndex != this._dealerIndex){
                    ePlayer.setAnte(1);
                    this.broadcast("onPlayerAddAnte", {
                        playerIndex: ePlayer.getIndex(),
                        num: 1
                    });
                }
            }.bind(this));
            this.broadcast("onAddAnteFinish", {});
            this._waitPlayCards();
        }.bind(this), this.getHideOption("addAnteWaitMS"));
    },

    /**
     * 用于加注结束之后给玩家多摸一张牌
     * @private
     */
    _waitPlayCards: function() {

        this._roundDateStamp = new Date().getTime();

        this.broadcast("onStartPlayCards", {
            playWaitTime: this.getHideOption("playWaitMS"),
            dateStamp: this._roundDateStamp
        });
        this._roundStatus = RoundStatus.PLAY;

        // 如果提前到下一步骤的话，那就先清空
        if(this._waitTimer){
            clearTimeout(this._waitTimer);
        }

        this._waitTimer = setTimeout(function() {
            if (this._roundStatus != RoundStatus.PLAY) {
                return;
            }
            this.enumPlayers(function(eIndex, ePlayer){
                if(ePlayer._playCards == false){
                    ePlayer.checkPattern();

                    var resp = {
                        playerIndex: ePlayer.getIndex(),
                        handCards: ePlayer.getHandCards().getInitCards(),
                        selectedCards: ePlayer._selectedCards,
                        niu: ePlayer._stat.roundPattern
                    };
                    this.broadcast("onPlayCards", resp);
                }
            }.bind(this));
            this.broadcast("onPlayCardsFinish", {});
            this.settlementCurRound();
        }.bind(this), this.getHideOption("playWaitMS"));
    },

    _waitSelectCards: function() {
        var room = this;
        this.enumPlayers(function(eIndex, ePlayer){
            if(room._publicCards.isEmpty()) {
                return;
            }
            var card = room._publicCards.getCard();
            ePlayer.addNewCard(card);

            var resp = {
                playerIndex: eIndex,
                card: card
            };
            ePlayer.send("onNewCard", resp);
        });

        this._roundStatus = RoundStatus.PLAY;
        this._selectWaitTime = Date.getStamp();
        this.broadcast("onStartSelectCards", {
            selectWaitTime: this.getHideOption("selectWaitMS")
        });

        this._waitTimer = setTimeout(function() {
            if (this._roundStatus != RoundStatus.PLAY) {
                return;
            }
            this.broadcast("onSelectCardsFinish", {});
            this.settlementCurRound();
        }.bind(this), this.getHideOption("selectWaitMS"));
    },

    _changeCurPlay: function(index){
        if(this._getPlayingPlayerCount() == 1 || this._roundTurn >= 10){
            this.settlementCurRound();
        }else{
            if(index){
                this._curPlay = index;
            }else{
                this._curPlay = this._getNextPlayer(this._curPlay);
            }
            this._sendCurPlay();
        }
    },

    _getPlayingPlayerCount: function () {
        var count = 0;
        this.enumPlaying(function (eIndex, ePlayer) {
            if(ePlayer._giveUp){
                return;
            }
            count += 1;
        });
        return count;
    },

    _getNextPlayer: function (fromIndex) {
        if (fromIndex < 1 || fromIndex > this.getMaxPlayer()) {
            fromIndex = 1;
        }
        var tmpIndex = fromIndex;
        do {
            tmpIndex = this.getNextIndex(tmpIndex);
            if(tmpIndex == 1){
                this._roundTurn += 1;
            }
            var tmpPlayer = this.getPlayerByIndex(tmpIndex);
            if (tmpPlayer && tmpPlayer.isPlaying() && tmpPlayer._giveUp == false) {
                break;
            }
        } while (tmpIndex != fromIndex);

        return tmpIndex;
    },

    _sendCurPlay: function() {
        var msg = {
            'curPlay': this._curPlay
        };
        this.broadcastReplay("onCurPlay", msg);
    }
});